package com.qianli.user.exception;

import com.alibaba.fastjson.JSON;
import com.fqgj.common.api.Response;
import com.fqgj.exception.common.ApiErrorException;
import com.qianli.user.UserHeadRequest;
import com.qianli.user.application.UserAccessApplication;
import com.qianli.user.domain.model.UserAccessModel;
import com.qianli.user.ro.BaseRO;
import com.qianli.user.ro.UserStateCode;
import com.qianli.user.ro.account.UserAccessRO;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.sql.SQLException;

/**
 * name:异常处理
 * auth:ting.li@yuntu-inc.com
 * date:2017/9/18下午2:53
 * version: v1.0.0
 **/
@Aspect
@Component
public class UserHandler {


    private static final Logger LOGGER = LoggerFactory.getLogger(UserHandler.class);

    @Autowired
    private UserAccessApplication userAccessApplication;

    @Pointcut("execution(* com.qianli.user.facade.impl.*.*(..)) || execution(* com.qianli.user.facade.impl.*.*.*(..))"
              + "|| execution(* com.qianli.user.facade.query.impl.*.*(..))||execution(* com.qianli.user.facade.query.impl.*.*.*(..))")
    private void externalPointCut(){}

    @Around("externalPointCut()")
    public Object readAround(ProceedingJoinPoint point) throws Throwable{
        Object result = null;
        try {
            long startTime = System.nanoTime();
            Object[] objs = point.getArgs();
            if(objs.length != 0){
                Object obj = objs[0];
                if(obj instanceof BaseRO){
                    BaseRO baseRO = (BaseRO)obj;
                    if(null == baseRO.getBiz()||null == baseRO.getAppCode()){
                        throw new ApiErrorException("biz and appCode can not be null");
                    }
                    if(null != baseRO.getUserCode()){
                        UserAccessModel accessModel = new UserAccessModel();
                        accessModel.setUserCode(baseRO.getUserCode());
                        accessModel.setAppCode(baseRO.getAppCode());
                        accessModel.setBiz(baseRO.getBiz());
                        Response<UserAccessRO> response = userAccessApplication.queryUserAccess(accessModel);
                        if(!response.isSuccess()){
                            throw new ApiErrorException(UserStateCode.USER_NOT_EXITS.getMsg());
                        }
                        UserHeadRequest.setThreadLocal(response.getData());
                    }
                }
            }
            result = point.proceed(objs);
//            long endTime = System.nanoTime();
//            long cost = (endTime-startTime)/1000000;
//            StringBuffer buffer = new StringBuffer(point.getTarget().getClass()+"."+point.getSignature().getName() +
//                            " method excute args:" + JSON.toJSONString(point.getArgs()) +",result:" +
//                            JSON.toJSONString(result));
//            if(cost>200){
//                buffer.append(",cost over 200") ;
//            }
//            buffer.append("real cost:" + cost);
//            LOGGER.info(buffer.toString());
        } catch (Exception e) {
            LOGGER.error(point.getTarget().getClass()+"."+point.getSignature().getName()+
                    " method excute error,args:" + JSON.toJSONString(point.getArgs()) +
                    ",result:" + JSON.toJSONString(result),e);

            if(e.getCause() instanceof SQLException){
                LOGGER.error("执行数据库操作出现异常,请求参数:{}"," service:"+point.getTarget().getClass()+
                        "."+point.getSignature().getName()+":"+JSON.toJSONString(point.getArgs()), e);
            }
            return e;
        }
        return result;
    }
}
